前幾天我們認識了自訂函式 def
的寫法,在昨天完成了第二個函式的程式碼;並且在提取函式的過程中,我們認識了 debug
內建函式的使用情境和方法。今天我們來認識 jq 的模組(module)。透過 jq module,可以幫助我們組織和重複使用程式碼。
徒弟:師父,我聽說 jq 有模組(module),它和其他程式語言的模組有什麼不同嗎?
師父:很好的問題!jq 的模組系統確實有其獨特之處。它允許我們將常用的函式(function)和表達式(filter)組織成可重複使用的程式碼單元,這對於大型專案或複雜的資料處理任務非常有用。
jq 模組(module)是一種將相關功能組織在一起的方式,可以提高程式碼的可讀性和可維護性。以下透過先前山陀兒颱風的例子,示範建立和使用 jq 模組的基本步驟:
建立一個檔名為 data_processing.jq
的檔案,內容如下:
首先先將原本定義寫在 main.jq
定義的函式 separate(f)
和 beaufort(f; wind_array)
,移到 data_processing.jq
之中。
使用 include 或 import 來導入模組。其中如果模組的.jq檔案和主程式不同目錄,則使用 -L
參數來指定模組的路徑;相同目錄則不需要此參數。
jq 提供了兩種導入模組的方式:import 和 include。它們有以下主要區別:
import "data_processing" as dp;
dp::separate("Hello,World")
include "data_processing";
separate("Hello,World")[0]
選擇使用 import 還是 include 取決於實際應用需求:
我們只有一個 module,因此使用 include 就足夠。main.jq
使用 include 初步修改如下:
include "data_processing";
.[0] as $direction | .[1] as $ty | .[2] as $wind |
...(略)...
更進一步,我打算根據 Day24: 認識 generator 概念 這篇整理的最外層結構來提取函式、擺放在模組中,有:
因此,我將 main.jq
改寫如下:
include "data_processing"; process_input | header, [ content ][] | @tsv
include 之後就是上面最外層結構的 1 | 2 | 3。
故還要再將原本寫在 main.jq 的部分提取至 data_processing.jq
模組裡面。提取後, data_processing.jq
增加了以下三個函式:
# 處理透過 slurp 讀進來的陣列,回傳物件
def process_input:
{
direction: .[0], # 來自 direction.json
typhoon: .[1], # 來自 typhoon1005.json
beaufort: .[2] # 來自 beaufort_wind.json
};
# 輸出固定標題,回傳字串陣列
def header:
["時間 ","經度","緯度","氣壓","風速MAX ","陣風MAX ","方向 ","預測"];
# 主要的資料內容,回傳颱風路徑陣列
def content:
.beaufort as $wind |
.direction as $direction |
.typhoon.records.tropicalCyclones.tropicalCyclone[] |
select(.typhoonName=="KRATHON") |
.analysisData.fix[-5:][] |
[
.fixTime[0:13],
separate(.coordinate)[0],
separate(.coordinate)[1],
.pressure,
beaufort(.maxWindSpeed; $wind),
beaufort(.maxGustSpeed; $wind),
$direction[.movingDirection],
.movingPrediction[0].value
];
在定義 process_input
也就是"1. 將各個輸入陣列元素儲存為變數"的時候,我稍微改變了原本的作法。原本直接使用 as $變數
的作法,改為直接將 slurp 輸入的陣列 -轉換- 成物件,用屬性的值存放輸入的陣列元素。好處在於,後續要取得可以直接使用 .direction
,.typhoon
,.beaufort
表達式。其他部分就照舊。
這樣看 main.jq 最外層的輸入/輸出結構一目了然;當然詳細還是要看模組裡面的函式定義囉。 今天修改的部分,可以參考 程式碼。
今天我們認識了 jq module 的寫法和使用方式,如此一來,就能把重複使用到的邏輯像是打包程式庫一樣,重複使用它;也可以按照我們期望的方式,將主程式安排成自己一看就懂的樣子,很棒。 👍
感謝今天的自己,認真的練習和學習。😄